package growTree;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.util.ArrayList;

import tree.Vector2d;

public class GrowTree {

	private double length;
	private double energy;
	private double thickness;

	private Vector2d pos;
	private Vector2d dir;
	private Vector2d endpoint;
	private ArrayList<GrowTree> branches;
	private boolean dead = false;
	
	public GrowTree(Vector2d pos, Vector2d dir) {
		this.pos = pos;
		this.dir = dir;
		endpoint = pos;
		length = 0;
		energy = 0;
		branches = new ArrayList<GrowTree>();
	}
	
	public GrowTree(Vector2d pos, Vector2d dir,double e) {
		this.pos = pos;
		this.dir = dir;
		endpoint = pos;
		length = 0;
		energy = e;
		thickness = 0;
		branches = new ArrayList<GrowTree>();
	}

	public void step(Vector2d npos) {
		pos = npos;
		endpoint = pos.add(dir.mult(length));
		if (energy < 1)
			return;
		
		energy += 0.01*branches.size();
		
		
		
		for (GrowTree branch : branches) {
			branch.step(endpoint);
			double totweight = 0;
			totweight += branch.thickness;
			dir.y += totweight/(15000*thickness);
			dir.Normalize();
			if (Math.random() > 0.8 && branch.energy < energy) {
				double egive = Math.random()/10;
				energy -= energy*egive;
				branch.energize(energy*egive);
			}
		}
		
		if(dead) return;
		
		//if(energy > 0.1){
		length += energy/1500;
		
		thickness += energy/5000;
		
		//energy *= 0.99;
		if (Math.random() > 0.9999) {
			dead = true;
		}
		
		if (Math.random() < energy/50000) {
			Vector2d dir2 = dir.add(Vector2d.randomVector().mult(0.5));
			dir2.Normalize();
			//double es = Math.random();
			//energy = (1-es)*energy;
			branches.add(new GrowTree(pos.add(dir.mult(energy)), dir2,0));

		}
	}

	public void energize(double e) {
		energy += e;
	}

	public void render(Graphics g) {
		if (energy < 0.1)
			return;
		for (GrowTree branch : branches) {
			branch.render(g);
		}
		Graphics2D g2 = (Graphics2D) g;
		float strokew = (float)thickness;
		//if(strokew > 20) strokew = 20;
		BasicStroke stroke = new BasicStroke(strokew);
		g2.setColor(Color.BLACK);
		g2.setStroke(stroke);

		g2.drawLine((int) (pos.x), (int) (pos.y),
				(int) endpoint.x, (int) endpoint.y);
		g2.setStroke(new BasicStroke(0.0f));
	}

}
